﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using BaseTypesLib.Interfaces;
using System.ComponentModel;
using System.Xml.Linq;

namespace BaseTypesLib.Model
{
    /// <summary>
    /// This is the base class for all field containers (managers)
    /// </summary>

    public enum ManagerLayout { Horizontal, Vertical, Custom }
    public abstract class Manager:Field, IUseAllWidth, IUseAllHeight
    {
        public Manager()
        {
            fields = new ObservableCollection<Field>();
            Focusable = false;
        }

        #region helper methods
        public void AddField(Field field)
        {
            if (fields.Contains(field)) return;
            if (field.Manager != null)
                field.Manager.RemoveField(field);
            field.Manager = this;
            fields.Add(field);
        }
        public void InsertField(int index, Field field)
        {
            if (fields.Contains(field)) return;
            if (field.Manager != null)
                field.Manager.RemoveField(field);
            field.Manager = this;
            fields.Insert(index, field);
        }
        public void RemoveField(Field field)
        {
            if (!fields.Contains(field)) return;
            field.Manager = null;
            fields.Remove(field);
        }
        #endregion

        #region scroll properties

        public bool HorizontalScroll
        {
            get { return hScroll; }
            set
            {
                if (hScroll != value)
                {
                    hScroll = value;
                    OnPropertyChanged("HorizontalScroll");
                }
            }
        }

        public bool VerticalScroll
        {
            get { return vScroll; }
            set
            {
                if (vScroll != value)
                {
                    vScroll = value;
                    OnPropertyChanged("VerticalScroll");
                }
            }
        }
        
        public bool HorizontalScrollBar
        {
            get { return hScrollBar; }
            set
            {
                if (hScrollBar != value)
                {
                    hScrollBar = value;
                    OnPropertyChanged("HorizontalScrollBar");
                }
            }
        }
        
        public bool VerticalScrollBar
        {
            get { return vScrollBar; }
            set
            {
                if (vScrollBar != value)
                {
                    vScrollBar = value;
                    OnPropertyChanged("VerticalScrollBar");
                }
            }
        }
        #endregion

        #region properties
        [Browsable(false)]
        public ObservableCollection<Field> Fields
        {
            get { return fields; }
        }
        
        public bool UseAllWidth
        {
            get { return useAllWidth; }
            set
            {
                if (useAllWidth != value)
                {
                    useAllWidth = value;
                    OnPropertyChanged("UseAllWidth");
                }
            }
        }
        
        public bool UseAllHeight
        {
            get { return useAllHeight; }
            set
            {
                if (useAllHeight != value)
                {
                    useAllHeight = value;
                    OnPropertyChanged("UseAllHeight");
                }
            }
        }
        #endregion

        public abstract ManagerLayout ManagerLayout { get; }

        private ObservableCollection<Field> fields;
        private bool hScroll, vScroll, hScrollBar, vScrollBar;
        private bool useAllWidth, useAllHeight;

        protected override XElement GetXmlElement()
        {
            XElement el = base.GetXmlElement();
            if (UseAllWidth) el.SetAttributeValue("UseAllWidth", UseAllWidth);
            if (UseAllHeight) el.SetAttributeValue("UseAllHeight", UseAllHeight);
            el.SetAttributeValue("HorizontalScroll", HorizontalScroll);
            el.SetAttributeValue("HorizontalScrollBar", HorizontalScrollBar);
            el.SetAttributeValue("VerticalScroll", VerticalScroll);
            el.SetAttributeValue("VerticalScrollBar", VerticalScrollBar);
            //focusable is false by default for managers.
            if (!Focusable) el.SetAttributeValue("Focusable", null);
            foreach (Field field in Fields)
                el.Add(field.GetXml());
            return el;
        }
        protected override void FromXmlElement(XElement elem)
        {
            base.FromXmlElement(elem);
            //add attributes
            var uaw = elem.Attributes("UseAllWidth").FirstOrDefault();
            if (uaw != null)
                UseAllWidth = (bool)uaw;
            var uah = elem.Attributes("UseAllHeight").FirstOrDefault();
            if (uah != null)
                UseAllHeight = (bool)uah;
            var hs = elem.Attributes("HorizontalScroll").FirstOrDefault();
            if (hs != null)
                HorizontalScroll = (bool)hs;
            var vs = elem.Attributes("VerticalScroll").FirstOrDefault();
            if (vs != null)
                VerticalScroll = (bool)vs;
            var hsb = elem.Attributes("HorizontalScrollBar").FirstOrDefault();
            if (hsb != null)
                HorizontalScrollBar = (bool)hsb;
            var vsb = elem.Attributes("VerticalScrollBar").FirstOrDefault();
            if (vsb != null)
                VerticalScrollBar = (bool)vsb;

            //add children
            var elems = elem.Elements().Where(p => p.Name.LocalName != "Background" &&
                p.Name.LocalName != "Font").ToList();
            foreach (XElement e in elems)
            {
                Field f = Field.FromXml(e);
                AddField(f);
            }
        }
    }
}
